package kuang.juc.cas;


import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicStampedReference;

//使用原子引用解决ABA问题，即乐观锁
public class ABADemo {
    public static void main(String[] args) {
        /**
         * Integer在-128到127之间是同一个对象，因为他维护了一个缓存，超过这个区间就创建新对象
         */
        AtomicStampedReference<Integer> integerAtomicStampedReference = new AtomicStampedReference<Integer>(1,1);

        new Thread(()->{
            //获取版本号
            int stamp = integerAtomicStampedReference.getStamp();
            System.out.println("A=>"+stamp);

            //保证AB线程都先获得相同版本号
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("A1:"+integerAtomicStampedReference.compareAndSet(1, 2,
                    integerAtomicStampedReference.getStamp(),
                    integerAtomicStampedReference.getStamp() + 1));

            System.out.println("A==>"+integerAtomicStampedReference.getStamp());


            //ABA狸猫换太子，值改回去，但是已经这个值是被动过的
            System.out.println("A2:"+integerAtomicStampedReference.compareAndSet(2, 1,
                    integerAtomicStampedReference.getStamp(),
                    integerAtomicStampedReference.getStamp() + 1));

            System.out.println("A===>"+integerAtomicStampedReference.getStamp());


        },"A").start();

        new Thread(()->{
            //获取版本号
            int stamp = integerAtomicStampedReference.getStamp();
            System.out.println("B=>"+stamp);

            //确保A线程已经完成ABA
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("B:"+integerAtomicStampedReference.compareAndSet(1, 2,
                    stamp,
                    stamp + 1));
            System.out.println("B===>"+integerAtomicStampedReference.getStamp());
        },"B").start();
    }
}
